package com.yuyuan.upload.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.qcloud.cos.model.PutObjectRequest;

import com.yuyuan.api.client.UserClient;
import com.yuyuan.api.domain.IconDTOC;
import com.yuyuan.common.domain.Result;
import com.yuyuan.common.utils.SystemConstants;
import com.yuyuan.common.utils.UserHolder;
import com.yuyuan.upload.service.IUploadService;
import com.yuyuan.upload.utils.COSUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @Author: kestrel
 * @Version:1.0
 * @Date: 2024/5/27
 */
@Slf4j
@Service
public class UploadServiceImpl implements IUploadService {

    @Autowired
    private UserClient userClient;

    @Override
    public String uploadImages(MultipartFile[] images) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < images.length; i++) {
            MultipartFile image = images[i];
            //获取文件原始名称
            String originalFilename = image.getOriginalFilename();
            //生成文件名
            String filePath = createNewFileName(originalFilename);
            String bucketName = "kestrel-1319254659";
            //拼接路径
            String key = "imgs" + filePath;
            File file = multipartFileToFile(image);
            //上传图片
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, file);
            COSUtils.cosClient.putObject(putObjectRequest);
            //返回结果
            log.debug("文件上传成功，{}", key);
            if (i > 0) result.append(',');
            result.append(key);
            //处理流传输生成的临时图片文件
            FileUtil.del(file);
        }
        return result.toString();
    }

    @Override
    public String uploadIconImage(MultipartFile image) {
        //获取文件原始名称
        String originalFilename = image.getOriginalFilename();
        //生成文件名
        String filePath = createNewFileName(originalFilename);
        String bucketName = "kestrel-1319254659";
        //拼接路径
        String key = "imgs" + filePath;
        File file = multipartFileToFile(image);
        try {
            //上传图片
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, file);
            COSUtils.cosClient.putObject(putObjectRequest);
            //更新数据库用户头像路径
            userClient.updateIcon(new IconDTOC(UserHolder.getUser().getId(), key));
        } catch (Exception e) {
            e.printStackTrace();
        }
        //返回结果
        log.debug("文件上传成功，{}", key);
        FileUtil.del(file);
        return key;
    }

    @Override
    public Result getCosTmpInfo() {
        List<String> result = new ArrayList<>(3);
        result.add(SystemConstants.TX_TMP_SECRET_ID);
        result.add(SystemConstants.TX_TMP_SECRET_KEY);
        result.add(SystemConstants.TX_TMP_SESSION_TOKEN);
        return Result.ok(result);
    }

    @Override
    public Result deleteBlogImage(String filePath) {
        String bucketName = SystemConstants.TX_BUCKET_NAME;
        COSUtils.cosClient.deleteObject(bucketName, filePath);
        return Result.ok();
    }

    /**
     * MultipartFile转换成File
     *
     * @param image 图片文件
     * @return File
     */
    private File multipartFileToFile(MultipartFile image) {
        File file = new File(image.getOriginalFilename());
        //使用try with resources结构使out自动关闭
        //获取文件流
        try (OutputStream out = new FileOutputStream(file)) {
            byte[] ss = image.getBytes();
            for (byte s : ss) {
                out.write(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }


    /**
     * 生成一个由哈希值组成的文件路径，增强系统安全性
     *
     * @param originalFilename 原始文件名
     * @return 生成的路径
     */
    private String createNewFileName(String originalFilename) {
        String suffix = StrUtil.subAfter(originalFilename, ".", true);
        //生成随机目录
        String name = UUID.randomUUID().toString();
        int hash = name.hashCode();
        int i1 = hash & 0xF;
        int i2 = (hash >> 4) & 0xF;
        //拼接文件名，并返回
        return StrUtil.format("/{}/{}/{}.{}", i1, i2, name, suffix);
    }
}
